From: Keir Fraser Date: Fri, 19 Oct 2007 08:28:21 +0000 (+0100) Subject: ia64: configure VHPT size per domain: ia64 part X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14847^2~18 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=641eac0d674886d04c2998a576141d5b74a017db;p=xen.git ia64: configure VHPT size per domain: ia64 part Signed-off-by: Kouya Shimura --- diff --git a/xen/arch/ia64/vmx/vmmu.c b/xen/arch/ia64/vmx/vmmu.c index 899774b687..3028f5d0ec 100644 --- a/xen/arch/ia64/vmx/vmmu.c +++ b/xen/arch/ia64/vmx/vmmu.c @@ -22,6 +22,7 @@ #include #include #include +#include static int default_vtlb_sz = DEFAULT_VTLB_SZ; static int default_vhpt_sz = DEFAULT_VHPT_SZ; @@ -38,17 +39,6 @@ static void __init parse_vtlb_size(char *s) } } -static int canonicalize_vhpt_size(int sz) -{ - /* minimum 32KB */ - if (sz < 15) - return 15; - /* maximum 8MB (since purging TR is hard coded) */ - if (sz > IA64_GRANULE_SHIFT - 1) - return IA64_GRANULE_SHIFT - 1; - return sz; -} - static void __init parse_vhpt_size(char *s) { int sz = parse_size_and_unit(s, NULL); @@ -96,8 +86,14 @@ static u64 get_mfn(struct domain *d, u64 gpfn) static int init_domain_vhpt(struct vcpu *v) { int rc; + u64 size = v->domain->arch.hvm_domain.params[HVM_PARAM_VHPT_SIZE]; + + if (size == 0) + size = default_vhpt_sz; + else + size = canonicalize_vhpt_size(size); - rc = thash_alloc(&(v->arch.vhpt), default_vhpt_sz, "vhpt"); + rc = thash_alloc(&(v->arch.vhpt), size, "vhpt"); v->arch.arch_vmx.mpta = v->arch.vhpt.pta.val; return rc; } diff --git a/xen/arch/ia64/xen/dom0_ops.c b/xen/arch/ia64/xen/dom0_ops.c index 9cf0576951..4f683561e2 100644 --- a/xen/arch/ia64/xen/dom0_ops.c +++ b/xen/arch/ia64/xen/dom0_ops.c @@ -93,6 +93,9 @@ long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) ds->maxmem = d->arch.convmem_end; ds->xsi_va = d->arch.shared_info_va; ds->hypercall_imm = d->arch.breakimm; +#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT + ds->vhpt_size_log2 = d->arch.vhpt_size_log2; +#endif /* Copy back. */ if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; @@ -116,6 +119,20 @@ long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) for_each_vcpu (d, v) v->arch.breakimm = d->arch.breakimm; } +#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT + if (ds->vhpt_size_log2 == -1) { + d->arch.has_pervcpu_vhpt = 0; + ds->vhpt_size_log2 = -1; + printk(XENLOG_INFO "XEN_DOMCTL_arch_setup: " + "domain %d VHPT is global.\n", d->domain_id); + } else { + d->arch.has_pervcpu_vhpt = 1; + d->arch.vhpt_size_log2 = ds->vhpt_size_log2; + printk(XENLOG_INFO "XEN_DOMCTL_arch_setup: " + "domain %d VHPT is per vcpu. size=2**%d\n", + d->domain_id, ds->vhpt_size_log2); + } +#endif if (ds->xsi_va) d->arch.shared_info_va = ds->xsi_va; ret = dom_fw_setup(d, ds->bp, ds->maxmem); diff --git a/xen/arch/ia64/xen/vhpt.c b/xen/arch/ia64/xen/vhpt.c index 0ca2d6e488..16d4d0140a 100644 --- a/xen/arch/ia64/xen/vhpt.c +++ b/xen/arch/ia64/xen/vhpt.c @@ -28,12 +28,13 @@ DEFINE_PER_CPU(volatile u32, vhpt_tlbflush_timestamp); #endif static void -__vhpt_flush(unsigned long vhpt_maddr) +__vhpt_flush(unsigned long vhpt_maddr, unsigned long vhpt_size_log2) { struct vhpt_lf_entry *v = (struct vhpt_lf_entry*)__va(vhpt_maddr); + unsigned long num_entries = 1 << (vhpt_size_log2 - 5); int i; - for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++) + for (i = 0; i < num_entries; i++, v++) v->ti_tag = INVALID_TI_TAG; } @@ -42,7 +43,7 @@ local_vhpt_flush(void) { /* increment flush clock before flush */ u32 flush_time = tlbflush_clock_inc_and_return(); - __vhpt_flush(__ia64_per_cpu_var(vhpt_paddr)); + __vhpt_flush(__ia64_per_cpu_var(vhpt_paddr), VHPT_SIZE_LOG2); /* this must be after flush */ tlbflush_update_time(&__get_cpu_var(vhpt_tlbflush_timestamp), flush_time); @@ -52,17 +53,23 @@ local_vhpt_flush(void) void vcpu_vhpt_flush(struct vcpu* v) { - __vhpt_flush(vcpu_vhpt_maddr(v)); + unsigned long vhpt_size_log2 = VHPT_SIZE_LOG2; +#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT + if (HAS_PERVCPU_VHPT(v->domain)) + vhpt_size_log2 = v->arch.pta.size; +#endif + __vhpt_flush(vcpu_vhpt_maddr(v), vhpt_size_log2); perfc_incr(vcpu_vhpt_flush); } static void -vhpt_erase(unsigned long vhpt_maddr) +vhpt_erase(unsigned long vhpt_maddr, unsigned long vhpt_size_log2) { struct vhpt_lf_entry *v = (struct vhpt_lf_entry*)__va(vhpt_maddr); + unsigned long num_entries = 1 << (vhpt_size_log2 - 5); int i; - for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++) { + for (i = 0; i < num_entries; i++, v++) { v->itir = 0; v->CChain = 0; v->page_flags = 0; @@ -140,7 +147,7 @@ void __init vhpt_init(void) __get_cpu_var(vhpt_pend) = paddr + (1 << VHPT_SIZE_LOG2) - 1; printk(XENLOG_DEBUG "vhpt_init: vhpt paddr=0x%lx, end=0x%lx\n", paddr, __get_cpu_var(vhpt_pend)); - vhpt_erase(paddr); + vhpt_erase(paddr, VHPT_SIZE_LOG2); // we don't enable VHPT here. // context_switch() or schedule_tail() does it. } @@ -151,6 +158,11 @@ pervcpu_vhpt_alloc(struct vcpu *v) { unsigned long vhpt_size_log2 = VHPT_SIZE_LOG2; + if (v->domain->arch.vhpt_size_log2 > 0) + vhpt_size_log2 = + canonicalize_vhpt_size(v->domain->arch.vhpt_size_log2); + printk(XENLOG_DEBUG "%s vhpt_size_log2=%ld\n", + __func__, vhpt_size_log2); v->arch.vhpt_entries = (1UL << vhpt_size_log2) / sizeof(struct vhpt_lf_entry); v->arch.vhpt_page = @@ -164,11 +176,11 @@ pervcpu_vhpt_alloc(struct vcpu *v) v->arch.pta.val = 0; // to zero reserved bits v->arch.pta.ve = 1; // enable vhpt - v->arch.pta.size = VHPT_SIZE_LOG2; + v->arch.pta.size = vhpt_size_log2; v->arch.pta.vf = 1; // long format v->arch.pta.base = __va_ul(v->arch.vhpt_maddr) >> 15; - vhpt_erase(v->arch.vhpt_maddr); + vhpt_erase(v->arch.vhpt_maddr, vhpt_size_log2); smp_mb(); // per vcpu vhpt may be used by another physical cpu. return 0; } @@ -178,7 +190,7 @@ pervcpu_vhpt_free(struct vcpu *v) { if (likely(v->arch.vhpt_page != NULL)) free_domheap_pages(v->arch.vhpt_page, - VHPT_SIZE_LOG2 - PAGE_SHIFT); + v->arch.pta.size - PAGE_SHIFT); } #endif diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index a605ac514f..7d2b5be64a 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -123,6 +123,7 @@ struct arch_domain { unsigned int is_vti : 1; #ifdef CONFIG_XEN_IA64_PERVCPU_VHPT unsigned int has_pervcpu_vhpt : 1; + unsigned int vhpt_size_log2 : 6; #endif }; }; diff --git a/xen/include/asm-ia64/vhpt.h b/xen/include/asm-ia64/vhpt.h index b0c988a322..17703d3659 100644 --- a/xen/include/asm-ia64/vhpt.h +++ b/xen/include/asm-ia64/vhpt.h @@ -84,5 +84,18 @@ vcpu_pta(struct vcpu* v) (VHPT_SIZE_LOG2 << 2) | VHPT_ENABLED; } +static inline int +canonicalize_vhpt_size(int sz) +{ + /* minimum 32KB */ + if (sz < 15) + return 15; + /* maximum 8MB (since purging TR is hard coded) */ + if (sz > IA64_GRANULE_SHIFT - 1) + return IA64_GRANULE_SHIFT - 1; + return sz; +} + + #endif /* !__ASSEMBLY */ #endif